package com.fingard.dsp.bankset;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fingard.FGBiz;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.core.dao.bankpay.BankPayInfoMapper;
import com.fingard.dsp.core.entity.bankpay.BankPayInfoPO;
import com.fingard.io.FileHelper;
import com.fingard.luna.framework.base.log.LogUtil;
import com.fingard.text.StringHelper;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigInteger;
import java.sql.Connection;
import java.text.SimpleDateFormat;
import java.util.*;

@Component
public class BankPayInfo {
    private final Logger logger = LogUtil.getLogger(this.getClass());
    public String bankFrontID = "";
    public String bankFrontKey = "";

    private static String replaceLetter = "@@flag";
    private static int maxStep = 10;
    private static int maxTableCount = 99;
    private static int initActiveDate = 100101;
    private static String initSqlPath = FGBiz.DSPHOME + "//dbScript//bankpayinfo.sql";
    private static String queryPayQueryBankFront = "select bpi.bank_front_id,bi.code,bi.entity,bi.system_code from tbl_dspcl_pay_info_" + replaceLetter + " bpi left join tbl_dspcl_bank_front bf on bpi.bank_front_id=bf.urid left join tbl_dspcl_bank_info bi on bi.urid=bf.bank_info_id where bpi.req_seq_id=?";
    private static String selectBankPayInfo = "select req_seq_id from tbl_dspcl_pay_info_" + replaceLetter + " where req_seq_id=?";
    private static String insertBankPayInfo = "insert into tbl_dspcl_pay_info_" + replaceLetter + " (urid,bank_front_id,trans_type,req_seq_id) value(?,?,?,?)";

    @Autowired(required = false)
    BankPayInfoMapper bankPayInfoMapper;

    public static boolean init(Connection p_conn, int p_count, int p_activeDate) throws Exception {
        if (p_count > maxTableCount) {
            throw new Exception("支付信息表个数输入有误，目前最大只支持99个！");
        }
        BankPayInfoHis bankPayInfoHis = new BankPayInfoHis(p_conn);
        bankPayInfoHis.queryHisInfo(p_activeDate);

        if (bankPayInfoHis.isSuccess) {
            if (bankPayInfoHis.count != p_count) {
                throw new Exception("当前暂只允许同个生效日内使用相同的表个数");
            } else {
                return true;
            }
        } else {
            Date currentTime = new Date();
            SimpleDateFormat formatter = new SimpleDateFormat("yyMMdd");
            String dateString = formatter.format(currentTime);
            if (p_activeDate <= Integer.parseInt(dateString) && p_activeDate != initActiveDate) {
                throw new Exception("当前暂只允许初始化当日之后的支付信息表");
            }
            for (int i = 1; i <= p_count; i++) {
                String tableFlag = p_activeDate + "" + (i < maxStep ? "0" + i : i + "");
                if (!generatePayInfoTable(p_conn, tableFlag)) {
                    throw new Exception("初始化支付信息表失败");
                } else {
                    System.out.println("已创建表：tbl_dspcl_pay_info_" + tableFlag);
                }
            }
            bankPayInfoHis.count = p_count;
            bankPayInfoHis.activeDate = p_activeDate;
            bankPayInfoHis.insertHisInfo();
            if (!bankPayInfoHis.isSuccess) {
                throw new Exception("初始化支付信息表失败");
            } else {
                return true;
            }

        }
    }

    public static boolean generatePayInfoTable(Connection p_conn, String p_tableFlag) throws Exception {
        String initSql = FileHelper.readFileText(initSqlPath, "UTF-8");
        if (!StringHelper.isNullOrEmpty(initSql)) {
            initSql = initSql.replace(replaceLetter, p_tableFlag).replace("\r", "");
            JDBCHelper.update(p_conn, initSql, new Object[]{});
            return true;
        } else {
            throw new Exception("支付信息表初始化脚本有误");
        }
    }

    public String getBankFront(String p_bgnDate, String p_reqSeqID) throws Exception {
        try {
            List<String> strings = Arrays.asList(p_reqSeqID);
            List<BankPayInfoPO> bankPayInfoPOS = bankPayInfoMapper.selectByReqSeqId(strings);
            if (bankPayInfoPOS == null || bankPayInfoPOS.size() == 0) {
                return "未找到该笔交易流水号的记录：" + p_reqSeqID;
            }
            //前置机配置在xml文件中时，从数据库中无法查询code、entity、systemcode等信息
            HashMap<String, BankFrontBalance> hashMapBankFront = FGBiz.dspCenter.bankFrontCenter.hashMapBankFront;
            Set<String> keySet = hashMapBankFront.keySet();
            boolean loopFlag = false;
            for (String key : keySet) {
                for (BankFront bankFront : hashMapBankFront.get(key).listBankFront) {
                    if (bankFront.urid.equals(bankPayInfoPOS.get(0).getBankfrontid())) {
                        this.bankFrontID = bankFront.urid;
                        this.bankFrontKey = bankFront.bankCode + "-" + bankFront.corporation + "-" + bankFront.group + "-" + bankFront.tenant;
                        logger.info("查找到的前置机：" + this.bankFrontKey);
                        loopFlag = true;
                        break;
                    }
                }
                if (loopFlag == true) {
                    break;
                }
            }
        } catch (Exception e) {
            return e.getMessage();
        }
        return null;
    }

    /**
     * 获取插入表的表名
     *
     * @param dbConn
     * @param p_bgnDate
     * @param p_reqSeqID
     * @return
     * @throws Exception
     */
    public String getBankPayInfoFlag(Connection dbConn, String p_bgnDate, String p_reqSeqID) throws Exception {
        BankPayInfoHis bankPayInfoHis = new BankPayInfoHis(dbConn);
        String flag = "";
        bankPayInfoHis.queryLastHisInfo(p_bgnDate);
        if (bankPayInfoHis.isSuccess) {
            BigInteger seqNo = new BigInteger(StringHelper.letterToNum(p_reqSeqID));
            seqNo = seqNo.remainder(new BigInteger(String.valueOf(bankPayInfoHis.count)));
            seqNo = seqNo.compareTo(BigInteger.ZERO) == 0 ? new BigInteger(String.valueOf(bankPayInfoHis.count)) : seqNo;
            flag = bankPayInfoHis.activeDate + "" + (seqNo.compareTo(new BigInteger(String.valueOf(maxStep))) < 0 ? "0" + seqNo : seqNo);
        }
        return flag;
    }


    /**
     * 查询T_DSP_BANKPAYINFO表中的流水号映射数据
     * 1.如果存在表示已发起支付，抛出异常，
     * 2.不存在则插入
     *
     * @param p_bgnDate
     * @param p_bankFrontID
     * @param p_transType
     * @param p_reqSeqID
     * @param isPckPayQuery
     * @return
     * @throws Exception
     */
    public boolean insertPayInfo(String p_bgnDate, String p_bankFrontID, String p_transType, List<String> p_reqSeqID, boolean isPckPayQuery) throws Exception {
        Date date = new Date();
        int resultCount = 0;
        for (String reqSeqID : p_reqSeqID) {
            BankPayInfoPO selectedPo = bankPayInfoMapper.selectOne(new QueryWrapper<BankPayInfoPO>().eq("REQSEQID", reqSeqID));
            if (selectedPo != null) {
                if (isPckPayQuery) {
                    resultCount++;
                    continue;
                } else {
                    throw new Exception("当前支付唯一标识" + selectedPo.getReqseqid() + "已存在，请核对！");
                }
            }
            BankPayInfoPO bankPayInfoPO = new BankPayInfoPO();
            bankPayInfoPO.setUrid(UUID.randomUUID().toString());
            bankPayInfoPO.setBankfrontid(p_bankFrontID);
            bankPayInfoPO.setReqseqid(reqSeqID);
            bankPayInfoPO.setTimestamp(date);
            bankPayInfoPO.setTranstype(p_transType);
            resultCount += bankPayInfoMapper.insert(bankPayInfoPO);
        }
        return resultCount == p_reqSeqID.size();
    }
}
